﻿//using Microsoft.AspNetCore.DataProtection;
//using Microsoft.AspNetCore.Http;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Text.RegularExpressions;
//using System.Threading.Tasks;

//namespace RuoVea.Application;

//public class DataProtectMiddleware
//{
//    private readonly RequestDelegate _next;
//    private readonly IDataProtector _dataProtector;

//    public DataProtectMiddleware(RequestDelegate requestDelegate, IDataProtectionProvider dataProtection)
//    {
//        _dataProtector = dataProtection.CreateProtector("defaultProtector");
//        _next = requestDelegate;
//    }

//    private static readonly string _matchJsonIdExpression = "\"[a-zA-Z0-9]+id\"";
//    private static readonly string _matchJsonIdValueExpression = "\"[a-zA-Z0-9_\\-]+\"";

//    private static readonly string _matchQueryIdExpression = "[a-zA-Z0-9]+id";
//    private static readonly string _matchQueryIdValueExpression = "[a-zA-Z0-9_\\-]+";

//    private Regex _matchJsonIdKeyValue = new Regex($"{_matchJsonIdExpression}:{_matchJsonIdValueExpression}", RegexOptions.IgnoreCase);
//    private Regex _matchQueryIdKeyValue = new Regex($"{_matchQueryIdExpression}={_matchQueryIdValueExpression}", RegexOptions.IgnoreCase);

//    public async Task Invoke(HttpContext context)
//    {
//        // 替换原本的 Response.Body 流在 _next(context) 执行下一个中间件后，需要读取数据，原本的流不可读 canReader = false
//        var originalResponseStream = context.Response.Body;
//        using var replaceResponseStream = new MemoryStream();

//        context.Response.Body = replaceResponseStream;

//        // 过滤请求
//        await FilterRequest(context);

//        await _next(context);

//        if (context.Response.StatusCode == StatusCodes.Status204NoContent)
//            return;

//        // 过滤响应
//        await FilterResponse(context, originalResponseStream, replaceResponseStream);
//    }

//    private async Task FilterResponse(HttpContext context, Stream originalResponseStream, MemoryStream replaceResponseStream)
//    {
//        var responseData = new StringBuilder();

//        using (var reader = new StreamReader(replaceResponseStream))
//        {
//            context.Response.Body.Seek(0, SeekOrigin.Begin);

//            responseData = new StringBuilder(await reader.ReadToEndAsync());
//            // 筛选以Id结尾的字段，并将ID加密
//            var matchedIdCollection = _matchJsonIdKeyValue.Matches(responseData.ToString());

//            foreach (Match itemMathId in matchedIdCollection)
//            {
//                var unprotectId = Regex.Match(itemMathId.Value, $"{_matchJsonIdValueExpression}$").Value.Replace("\"", "");
//                var protectId = Regex.Replace(itemMathId.Value,
//                    $"{_matchJsonIdValueExpression}$",
//                    $"\"{_dataProtector.Protect(unprotectId)}\"");

//                responseData = responseData.Replace(itemMathId.Value, protectId);
//            }
//        }

//        // 将返回的 Response 流 Copy 到原始流
//        await originalResponseStream.WriteAsync(Encoding.Default.GetBytes(responseData.ToString()));

//        context.Response.Body = originalResponseStream;
//    }

//    private async Task<HttpContext> FilterRequest(HttpContext context)
//    {
//        // 可以考虑反序列化为对象，更加灵活控制加密字段，这里使用正则因为 简单，粗暴，快 反射要慢一点
//        var requestData = new StringBuilder();

//        // 过滤 Get 请求中 QueryString 的 Id 值，并解密
//        if (context.Request.Method.Equals(HttpMethods.Get, StringComparison.CurrentCultureIgnoreCase))
//        {
//            requestData.Append(context.Request.QueryString);
//            var matchedIdCollection = _matchQueryIdKeyValue.Matches(requestData.ToString());
//            foreach (Match itemMathId in matchedIdCollection)
//            {
//                var protectId = Regex.Match(itemMathId.Value, $"{_matchQueryIdValueExpression}$").Value;
//                var unprotectId = Regex.Replace(itemMathId.Value,
//                    $"{_matchQueryIdValueExpression}$",
//                    $"{_dataProtector.Unprotect(protectId)}");

//                requestData = requestData.Replace(itemMathId.Value, unprotectId);
//            }

//            context.Request.QueryString = new QueryString(requestData.ToString());
//        }

//        if (context.Request.Method.Equals(HttpMethods.Post, StringComparison.CurrentCultureIgnoreCase))
//        {
//            // 过滤 Post 请求 Body Stream 中的 Id 值，并解密
//            using (var reader = new StreamReader(context.Request.Body))
//            {
//                requestData.Append(await reader.ReadToEndAsync());

//                var matchedIdCollection = _matchJsonIdKeyValue.Matches(requestData.ToString());

//                foreach (Match itemMathId in matchedIdCollection)
//                {
//                    var protectId = Regex.Match(itemMathId.Value, $"{_matchJsonIdValueExpression}$").Value.Replace("\"", "");
//                    var unProtectId = Regex.Replace(itemMathId.Value,
//                        $"{_matchJsonIdValueExpression}$",
//                        $"\"{_dataProtector.Unprotect(protectId)}\"");

//                    requestData = requestData.Replace(itemMathId.Value, unProtectId);
//                }
//            }

//            var requestStringContent = new StringContent(requestData.ToString());

//            context.Request.Body = await requestStringContent.ReadAsStreamAsync();
//        }

//        return context;
//    }
//}

